// 版权归 Epic Games, Inc. 所有。保留所有权利。

#pragma once

#include "OnlineHotfixManager.h"
#include "Misc/CoreDelegates.h"
#include "Containers/Ticker.h"
#include "LyraHotfixManager.generated.h"

UCLASS()
class ULyraHotfixManager : public UOnlineHotfixManager
{
	GENERATED_BODY()

public:
	/** 声明一个多播委托，用于通知游戏热修复待处理状态变化 */
	DECLARE_MULTICAST_DELEGATE_OneParam(FOnPendingGameHotfix, bool);
	/** 当有游戏热修复待处理时广播的委托 */
	FOnPendingGameHotfix OnPendingGameHotfixChanged;

	/** 构造函数 */
	ULyraHotfixManager();
	/** 析构函数 */
	virtual ~ULyraHotfixManager();

	/** 请求从INI文件修补资源 */
	void RequestPatchAssetsFromIniFiles();

protected:
	/** 热修复完成时的回调函数 */
	void OnHotfixCompleted(EHotfixResult HotfixResult);

	/** 获取缓存目录路径 */
	virtual FString GetCachedDirectory() override
	{
		return FPaths::ProjectPersistentDownloadDir() / TEXT("Hotfix/");
	}

	/** 开始热修复过程 */
	virtual void StartHotfixProcess() override;

	/** 判断是否需要对文件进行热修复处理 */
	virtual bool WantsHotfixProcessing(const struct FCloudFileHeader& FileHeader) override;
	/** 应用热修复处理 */
	virtual bool ApplyHotfixProcessing(const struct FCloudFileHeader& FileHeader) override;
	/** 判断在从INI文件修补时是否应警告缺失的资源 */
	virtual bool ShouldWarnAboutMissingWhenPatchingFromIni(const FString& AssetPath) const override;
	/** 从INI文件修补资源 */
	virtual void PatchAssetsFromIniFiles() override;

	/** 检查热修复可用性时的回调 */
	virtual void OnHotfixAvailablityCheck(const TArray<FCloudFileHeader>& PendingChangedFiles, const TArray<FCloudFileHeader>& PendingRemoveFiles) override;

	/** 热修复INI文件 */
	virtual bool HotfixIniFile(const FString& FileName, const FString& IniData) override;

private:
#if !UE_BUILD_SHIPPING
	// 错误报告
	FDelegateHandle OnScreenMessageHandle; // 屏幕消息委托句柄
	/** 获取屏幕消息 */
	void GetOnScreenMessages(TMultiMap<FCoreDelegates::EOnScreenMessageSeverity, FText>& OutMessages);
#endif // !UE_BUILD_SHIPPING

private:
	/** 获取当前游戏实例 */
	template<typename T>
	T* GetGameInstance() const
	{
		return GetTypedOuter<T>();
	}

	/** 初始化函数 */
	void Init() override;

private:
	FTSTicker::FDelegateHandle RequestPatchAssetsHandle; // 请求修补资源委托句柄
	FDelegateHandle HotfixCompleteDelegateHandle; // 热修复完成委托句柄

	bool bHasPendingGameHotfix = false; // 是否有待处理的游戏热修复
	bool bHasPendingDeviceProfileHotfix = false; // 是否有待处理的设备配置热修复

	static int32 GameHotfixCounter; // 游戏热修复计数器
};